package losrebellos.lospistoleros.components.preloader.sprite 
{
	import br.com.stimuli.loading.BulkLoader;
	import br.com.stimuli.loading.BulkProgressEvent;
	import br.com.stimuli.loading.loadingtypes.LoadingItem;

	import losrebellos.console.Console;
	import losrebellos.lospistoleros.components.application.sprite.base.BasePApplicationModelSprite;
	import losrebellos.lospistoleros.components.preloader.IPPreloaderModel;
	import losrebellos.lospistoleros.constants.PConstants;
	import losrebellos.lospistoleros.core.view.IPView;
	import losrebellos.lospistoleros.data.SWF;
	import losrebellos.lospistoleros.data.asset.Assets;
	import losrebellos.lospistoleros.data.content.Content;
	import losrebellos.lospistoleros.data.font.Fonts;
	import losrebellos.lospistoleros.data.style.TextFormats;
	import losrebellos.lospistoleros.events.PPreloaderEvent;
	import losrebellos.lospistoleros.vo.ApplicationVO;
	import losrebellos.lospistoleros.vo.AssetVO;
	import losrebellos.net.URLLoaderPlus;

	import flash.display.MovieClip;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;

	/*
	 *
	 * @author los rebellos - ben@benoitvinay.com
	 *
	 */
	public class PPreloaderModelSprite extends BasePApplicationModelSprite implements IPPreloaderModel 
	{
		/*
		 *
		 * VARIABLES
		 *
		 */
		//lang
		protected var _lang:String = Content.DEFAULT_LANGUAGE;
		protected var _applicationVO:ApplicationVO = null;
		//assets xml
		protected var _assetsLoader:URLLoaderPlus;
		protected var _assetsXML:XML;
		
		
		/*
		 *
		 * CONSTRUCTOR
		 *
		 */
		public function PPreloaderModelSprite(name:String = null, type:String = null)
		{
			super(name, type);
		}
		
		
		/*
		 * 
		 * LANGUAGE
		 * 
		 */
		public function set lang(value:String):void
		{
			_lang = value;
		}
		
		
		/*
		 * 
		 * APPLICATION
		 * 
		 */
		public function get applicationVO():ApplicationVO
		{
			if(!_applicationVO)
			{
				_applicationVO = createApplicationVO();
			}
			
			return _applicationVO;
		}
		protected function createApplicationVO():ApplicationVO
		{
			return new ApplicationVO();
		}
		
		
		/*
		 * 
		 * LOAD ASSETS
		 * 
		 */
		public function loadAssetsXML(request:URLRequest):void
		{
			_assetsLoader = new URLLoaderPlus();
			_assetsLoader.dataFormat = URLLoaderDataFormat.TEXT;
			_assetsLoader.addEventListener(ProgressEvent.PROGRESS, progressAssetsXMLHandler);
			_assetsLoader.addEventListener(Event.COMPLETE, completeAssetsXMLHandler);
			_assetsLoader.addEventListener(ErrorEvent.ERROR, errorAssetsXMLHandler);
			_assetsLoader.load(request);
		}

		
		/*
		 * 
		 * ASSETS XML HANDLERS
		 * 
		 */
		protected function progressAssetsXMLHandler(e:ProgressEvent):void
		{
			this.dispatchEvent(new PPreloaderEvent(PPreloaderEvent.PROGRESS, e.bytesLoaded / e.bytesTotal));
		}
		protected function errorAssetsXMLHandler(e:ErrorEvent):void
		{
			_assetsLoader.removeEventListener(ProgressEvent.PROGRESS, progressAssetsXMLHandler);
			_assetsLoader.removeEventListener(Event.COMPLETE, completeAssetsXMLHandler);
			_assetsLoader.removeEventListener(ErrorEvent.ERROR, errorAssetsXMLHandler);
			
			this.dispatchEvent(new PPreloaderEvent(PPreloaderEvent.ERROR));
		}
		protected function completeAssetsXMLHandler(e:Event):void
		{
			_assetsLoader.removeEventListener(ProgressEvent.PROGRESS, progressAssetsXMLHandler);
			_assetsLoader.removeEventListener(Event.COMPLETE, completeAssetsXMLHandler);
			_assetsLoader.removeEventListener(ErrorEvent.ERROR, errorAssetsXMLHandler);
			
			_assetsXML = XML(e.target["data"]);
			
			this.dispatchEvent(new PPreloaderEvent(PPreloaderEvent.COMPLETE));
		}
		
		
		/*
		 * 
		 * ASSETS
		 * 
		 */
		public function loadAssets():void
		{
			parseGeneralAssetsXML();
			parseLocalizeAssetsXML();
			
			Assets.instance.addEventListener(BulkProgressEvent.PROGRESS, progressAssetsHandler);
			Assets.instance.addEventListener(BulkLoader.COMPLETE, completeAssetsHandler);
			Assets.instance.addEventListener(BulkLoader.ERROR, errorAssetsHandler);
			Assets.instance.start();
		}
		
		
		/*
		 * 
		 * PARSING OF THE ASSETS XML
		 * 
		 */
		// general assets
		protected function parseGeneralAssetsXML():void
		{
			var xmlListAssets:XMLList = _assetsXML["asset"];
			for(var i:int = 0; i<xmlListAssets.length(); i++)
			{
				var asset:AssetVO = new AssetVO(String(xmlListAssets[i].@src), String(xmlListAssets[i].@loadingType), String(xmlListAssets[i].@id), String(xmlListAssets[i].@parsingType));
				var loadingItem:LoadingItem = Assets.instance.add(asset.src, {id:asset.id, type:asset.loadingType, asset:asset});
				loadingItem.addEventListener(BulkLoader.COMPLETE, itemCompleteHandler);
				loadingItem.addEventListener(BulkLoader.ERROR, errorHandler);
			}
		}
		protected function parseLocalizeAssetsXML():void
		{
			// content assets
			var xmlListContents:XMLList = _assetsXML["content"];
			for(var i:int = 0; i<xmlListContents.length(); i++)
			{
				// localization
				if(String(xmlListContents[i].@lang) == _lang)
				{
					// assets
					var xmlListAssets:XMLList = xmlListContents[i]["asset"];
					for(var j:int = 0; j<xmlListAssets.length(); j++)
					{
						var asset:AssetVO = new AssetVO(String(xmlListAssets[j].@src), String(xmlListAssets[j].@loadingType), String(xmlListAssets[j].@id), String(xmlListAssets[j].@parsingType));
						var loadingItem:LoadingItem = Assets.instance.add(asset.src, {id:asset.id, type:asset.loadingType, asset:asset});
						loadingItem.addEventListener(BulkLoader.COMPLETE, itemCompleteHandler);
						loadingItem.addEventListener(BulkLoader.ERROR, errorHandler);
					}
				}
			}
		}
		
		
		/*
		 * 
		 * ASSETS HANDLERS
		 * 
		 */
		protected function progressAssetsHandler(e:BulkProgressEvent):void
		{
			this.dispatchEvent(new PPreloaderEvent(PPreloaderEvent.PROGRESS, e.percentLoaded));
		}
		protected function completeAssetsHandler(e:Event):void
		{
			Assets.instance.removeEventListener(BulkProgressEvent.PROGRESS, progressAssetsHandler);
			Assets.instance.removeEventListener(BulkLoader.COMPLETE, completeAssetsHandler);
			Assets.instance.removeEventListener(BulkLoader.ERROR, errorAssetsHandler);
			
			this.dispatchEvent(new PPreloaderEvent(PPreloaderEvent.COMPLETE));
		}
		protected function errorAssetsHandler(e:ErrorEvent):void
		{
			Assets.instance.removeEventListener(BulkProgressEvent.PROGRESS, progressAssetsHandler);
			Assets.instance.removeEventListener(BulkLoader.COMPLETE, completeAssetsHandler);
			Assets.instance.removeEventListener(BulkLoader.ERROR, errorAssetsHandler);
			
			this.dispatchEvent(new PPreloaderEvent(PPreloaderEvent.ERROR));
		}
		
		
		/*
		 * 
		 * LOADING ITEM MANAGEMENT
		 * 
		 */
		private function itemCompleteHandler(e:Event):void
		{
			var loadingItem:LoadingItem = e.currentTarget as LoadingItem;
			loadingItem.removeEventListener(BulkLoader.COMPLETE, itemCompleteHandler);
			loadingItem.removeEventListener(BulkLoader.ERROR, errorHandler);
			
			// content & fonts
			var asset:AssetVO = Assets.instance.getAssetVO(loadingItem.id);
			switch(asset.parsingType)
			{
				case PConstants.TYPE_FONTS:
					registerFonts(asset.id);
					break;
				
				case PConstants.TYPE_CONTENT:
					registerContent(asset.id);
					break;
				
				case PConstants.TYPE_CSS:
					registerCSS(asset.id);
					break;
				
				case PConstants.ASSET_INDEX:
				case PConstants.ASSET_ASSETS:
					Console.simpleOutput("PPreloaderModelSprite:itemCompleteHandler => " + asset.parsingType + " (" + asset.id + ") loaded");
				default:
					itemComplete(asset);
					break;
			}
		}
		private function errorHandler(e:ErrorEvent):void
		{
			var loadingItem:LoadingItem = e.currentTarget as LoadingItem;
			loadingItem.removeEventListener(BulkLoader.COMPLETE, itemCompleteHandler);
			loadingItem.removeEventListener(BulkLoader.ERROR, errorHandler);
			
			Console.output(this, "PPreloaderModelSprite => " + loadingItem.id + " error: " + e);
		}
		
		
		/*
		 * 
		 * SPECIFIC ASSETS
		 * 
		 */
		protected function registerFonts(id:String):void
		{
			var tabFonts:Array = SWF.parse(Assets.instance.getByteArray(id));
			var mcFonts:MovieClip = Assets.instance.getMovieClip(id);
			Fonts.instance.register(tabFonts, mcFonts);
			
			Console.output(this, "Fonts: " + id + " registered");
		}
		protected function registerContent(id:String):void
		{
			Content.instance.register(Assets.instance.getXML(id));
			
			Console.output(this, "Content: " + id + " registered");
		}
		protected function registerCSS(id:String):void
		{
			Console.output(this, "CSS: " + id + " registered => " + TextFormats.instance.registerStyleSheet(id, Assets.instance.getStyleSheet(id)));
		}
		protected function itemComplete(asset:AssetVO):void
		{
			Console.simpleOutput("PPreloaderModelSprite:itemComplete => " + asset);
		}
		
		
		/*
		 * 
		 * INDEX
		 * 
		 */
		public function getIndex():IPView
		{
			return Assets.instance.getContent(_applicationVO.index);
		}
	}
}